package com.example.myweb.Security;

import com.example.myweb.Service.JwtBlacklistService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;


import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private CustomUserDetailsService customUserDetailsService;
    @Autowired
    private JwtBlacklistService jwtBlacklistService; // <-- 注入 JwtBlacklistService

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain filterChain
    ) throws ServletException, IOException {
        final String authHeader = request.getHeader("Authorization");
        final String jwt;
        final String userEmail;

        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);
            return;
        }

        jwt = authHeader.substring(7);
        userEmail = jwtUtil.extractUsername(jwt);

        if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.customUserDetailsService.loadUserByUsername(userEmail);

            // 1. 首先验证 JWT 的有效性 (签名、格式、过期时间)
            if (jwtUtil.validateToken(jwt, userDetails)) { // 这个方法内部会检查过期
                // 2. 关键一步：如果 JWT 本身有效，则检查它是否在黑名单中
                if (jwtBlacklistService.isBlacklisted(jwt)) { // <-- 添加这一行
                    System.out.println("JWT [" + jwt.substring(0, 20) + "...] 在黑名单中，拒绝访问。");
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 返回401未授权状态码
                    response.setContentType("application/json"); // 设置响应类型
                    response.getWriter().write("{\"code\": 401, \"message\": \"Token has been blacklisted.\"}"); // 返回JSON格式错误信息
                    return; // 阻止请求继续处理
                }

                // 3. 如果 JWT 有效且不在黑名单中，则设置认证信息
                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                        userDetails,
                        null,
                        userDetails.getAuthorities()
                );
                authToken.setDetails(
                        new WebAuthenticationDetailsSource().buildDetails(request)
                );
                SecurityContextHolder.getContext().setAuthentication(authToken);
                System.out.println("JWT [" + jwt.substring(0, 20) + "...] 验证通过并设置认证信息。");
            } else {
                System.out.println("JWT [" + jwt.substring(0, 20) + "...] 验证失败或已过期。");
            }
        }
        filterChain.doFilter(request, response);
    }
}